home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / By the Book / Mac C Primer V2 / 6.1 - MyStarter / CStarterDoc.c < prev    next >
Text File  |  1991-08-23  |  11KB  |  473 lines

  1. /************************************************************/
  2. /*                                                            */
  3. /*    CStarterDoc Code from Chapter Six of                    */
  4. /*                                                            */
  5. /*        *** The Macintosh Programming Primer ***            */
  6. /*                                                            */
  7. /*    Copyright 1990, Dave Mark                                */
  8. /*                                                            */
  9. /*    This program demonstrates specific Mac programming        */
  10. /*    techniques.                                                */
  11. /*                                                            */
  12. /************************************************************/
  13.  
  14. /****
  15.  * CStarterDoc.c
  16.  *
  17.  *    Document methods for a typical application.
  18.  *
  19.  *  Copyright © 1990 Symantec Corporation.  All rights reserved.
  20.  *
  21.  ****/
  22.  
  23. #include <Global.h>
  24. #include <Commands.h>
  25. #include <CApplication.h>
  26. #include <CBartender.h>
  27. #include <CDataFile.h>
  28. #include <CDecorator.h>
  29. #include <CDesktop.h>
  30. #include <CError.h>
  31. #include <CPanorama.h>
  32. #include <CScrollPane.h>
  33. #include "CStarterDoc.h"
  34. #include "CStarterPane.h"
  35. #include "TBUtilities.h"
  36. #include "CWindow.h"
  37. #include <Packages.h>
  38.  
  39.  
  40. #define    WINDStarter        500        /* Resource ID for WIND template */
  41.  
  42. extern    CApplication *gApplication;    /* The application */
  43. extern    CBartender    *gBartender;    /* The menu handling object */
  44. extern    CDecorator    *gDecorator;    /* Window dressing object    */
  45. extern    CDesktop    *gDesktop;        /* The enclosure for all windows */
  46. extern    CBureaucrat    *gGopher;        /* The current boss in the chain of command */
  47. extern    OSType        gSignature;        /* The application's signature */
  48. extern    CError        *gError;        /* The global error handler */
  49.  
  50. /***
  51.  * IStarterDoc
  52.  *
  53.  *    This is your document's initialization method.
  54.  *    If your document has its own instance variables, initialize
  55.  *    them here.
  56.  *
  57.  *    The least you need to do is invoke the default method.
  58.  *
  59.  ***/
  60.  
  61.  /* Altered by TCL Demo Weaver 1.0 (2/21/90) */
  62.  
  63. void CStarterDoc::IStarterDoc(CApplication *aSupervisor, Boolean printable)
  64.  
  65. {
  66.     CDocument::IDocument(aSupervisor, printable);
  67. }
  68.  
  69.  
  70. /***
  71.  * Dispose
  72.  *
  73.  *    This is your document's destruction method.
  74.  *    If you allocated memory in your initialization method
  75.  *    or opened temporary files, this is the place to release them.
  76.  *
  77.  *    Be sure to call the default method!
  78.  *
  79.  ***/
  80.  
  81. void CStarterDoc::Dispose()
  82.  
  83. {
  84.     inherited::Dispose();
  85. }
  86.  
  87.  
  88. /***
  89.  * DoCommand
  90.  *
  91.  *    This is the heart of your document.
  92.  *    In this method, you handle all the commands your document
  93.  *    deals with.
  94.  *
  95.  *    Be sure to call the default method to handle the standard
  96.  *    document commands: cmdClose, cmdSave, cmdSaveAs, cmdRevert,
  97.  *    cmdPageSetup, cmdPrint, and cmdUndo. To change the way these
  98.  *    commands are handled, override the appropriate methods instead
  99.  *    of handling them here.
  100.  *
  101.  ***/
  102.  
  103. void CStarterDoc::DoCommand(long theCommand)
  104.  
  105. {
  106.     switch (theCommand) {
  107.  
  108.         /* your document commands here */
  109.     
  110.         default:    inherited::DoCommand(theCommand);
  111.                     break;
  112.     }
  113. }
  114.  
  115.  
  116. /* Altered by TCL Demo Weaver 1.0 (2/21/90) */
  117.  
  118. /***
  119.  * UpdateMenus
  120.  *
  121.  *  In this method you can enable menu commands that apply when
  122.  *  your document is active.
  123.  *
  124.  *  Be sure to call the inherited method to get the default behavior.
  125.  *  The inherited method enables these commands: cmdClose, cmdSaveAs,
  126.  *  cmdSave, cmdRevert, cmdPageSetup, cmdPrint, cmdUndo.
  127.  *
  128. ***/
  129.  
  130.  void CStarterDoc::UpdateMenus()
  131.  
  132.  {
  133.   inherited::UpdateMenus();
  134.  
  135.     /* Enable your menu commands here (enable each one with a call to   
  136.        gBartender->EnableCmd(command_number)).  
  137.     */                      
  138.  
  139.  }
  140.  
  141.  
  142. /***
  143.  * NewFile
  144.  *
  145.  *    When the user chooses New from the File menu, the CreateDocument()
  146.  *    method in your Application class will send a newly created document
  147.  *    this message. This method needs to create a new window, ready to
  148.  *    work on a new document.
  149.  *
  150.  *    Since this method and the OpenFile() method share the code for creating
  151.  *    the window, you should use an auxiliary window-building method.
  152.  *
  153.  ***/
  154. void CStarterDoc::NewFile(void)
  155.  
  156. {
  157.     /* Altered by TCL Demo Weaver 1.0 (2/21/90) */
  158.     
  159.     Str255  wTitle;     /* Window title string.         */
  160.     short   wCount;     /* Index number of new window.  */
  161.     Str255  wNumber;    /* Index number as a string.    */
  162.     
  163.         /**
  164.          **    BuildWindow() is the method that
  165.          **    does the work of creating a window.
  166.          ** Its parameter should be the data that
  167.          **    you want to display in the window.
  168.          **    Since this is a new window, there's nothing
  169.          **    to display.
  170.          **
  171.          **/
  172.  
  173.     BuildWindow(NULL);
  174.     
  175.         /**
  176.          ** Append an index number to the
  177.          ** default name of the window.
  178.          **/
  179.          
  180.     itsWindow->GetTitle(wTitle);
  181.     wCount = gDecorator->GetWCount();
  182.     NumToString(wCount, wNumber);
  183.     ConcatPStrings(wTitle, "\p ");
  184.     ConcatPStrings(wTitle, wNumber);
  185.     itsWindow->SetTitle(wTitle);
  186.  
  187.         /**
  188.          **    Send the window a Select() message to make
  189.          **    it the active window.
  190.          **/
  191.     
  192.     itsWindow->Select();
  193. }
  194.  
  195.  
  196. /***
  197.  * OpenFile
  198.  *
  199.  *    When the user chooses Open… from the File menu, the OpenDocument()
  200.  *    method in your Application class will let the user choose a file
  201.  *    and then send a newly created document this message. The information
  202.  *    about the file is in the SFReply record.
  203.  *
  204.  *    In this method, you need to open the file and display its contents
  205.  *    in a window. This method uses the auxiliary window-building method.
  206.  *
  207.  ***/
  208.  
  209. void CStarterDoc::OpenFile(SFReply *macSFReply)
  210.  
  211. {
  212.     CDataFile    *theFile;
  213.     Handle        theData;
  214.     Str63        theName;
  215.     OSErr        theError;
  216.  
  217.         /**
  218.          ** Create a file and send it a SFSpecify()
  219.          **    message to set up the name, volume, and
  220.          **    directory.
  221.          **
  222.          **/
  223.  
  224.     theFile = new(CDataFile);
  225.     theFile->IDataFile();
  226.     theFile->SFSpecify(macSFReply);
  227.     
  228.         /**
  229.          **    Be sure to set the instance variable
  230.          **    so other methods can use the file if they
  231.          **    need to. This is especially important if
  232.          **    you leave the file open in this method.
  233.          **    If you close the file after reading it, you
  234.          **    should be sure to set itsFile to NULL.
  235.          **
  236.          **/
  237.  
  238.     itsFile = theFile;
  239.  
  240.         /**
  241.          **    Send the file an Open() message to
  242.          **    open it. You can use the ReadSome() or
  243.          **    ReadAll() methods to get the contents of the file.
  244.          **
  245.          **/
  246.  
  247.     theFile->Open(fsRdWrPerm);
  248.  
  249.         /**
  250.          **    Check to see if we were able to open
  251.          **    the file. Send the error handler
  252.          **    a CheckOSError() message. If there was
  253.          **    an error, CheckOSError returns false
  254.          **    and reports the error in an alert.
  255.          **    The default error message displays the
  256.          **    error number.
  257.          **    You can use Estr resources to customize
  258.          **    the error message.
  259.          **
  260.          **    Note that we send ourselves a Dispose()
  261.          **    message. Since we're not going to open,
  262.          **    we should get rid of the object.
  263.          **/
  264.  
  265.     if (!gError->CheckOSError(theError)) {
  266.         Dispose();
  267.         return;
  268.     }
  269.  
  270.         /**
  271.          **    Make sure that the memory request to read
  272.          **    the data from the file doesn't use up any
  273.          **    of our rainy day fund and that the GrowMemory()
  274.          **    method (in the application) knows that it's OK
  275.          **    if we couldn't get enough memory.
  276.          **
  277.          **/
  278.  
  279.     /* Altered by TCL Demo Weaver 1.0 (2/21/90) */
  280.  
  281.     /*gApplication->RequestMemory(FALSE, TRUE);*/
  282.     /*theFile->ReadAll(&theData);  */   /* ReadAll() creates the handle */
  283.     
  284.     /* Reset canFail to FALSE for default memory-error handling. */
  285.     
  286.     /*gApplication->RequestMemory(FALSE, FALSE);*/
  287.  
  288.  
  289.         /**
  290.          **    If there isn't enough memory to open,
  291.          **    post the error (should be -108)
  292.          ** and get rid of ourselves.
  293.          **
  294.          **/
  295.  
  296.     if (theData == NULL) {
  297.         gError->CheckOSError(MemError());
  298.         Dispose();
  299.         return;
  300.     }
  301.  
  302.     
  303.     BuildWindow(theData);
  304.  
  305.         /**
  306.          **    In your application, you'll probably store
  307.          **    the data in some form as an instance variable
  308.          **    in your document class. For this example, there's
  309.          **    no need to save it, so we'll get rid of it.
  310.          **
  311.          **/
  312.  
  313.     DisposHandle(theData);
  314.  
  315.         /**
  316.          **    In this implementation, we leave the file
  317.          **    open. You might want to close it after
  318.          **    you've read in all the data.
  319.          **
  320.          **/
  321.  
  322.     itsFile->GetName(theName);
  323.     itsWindow->SetTitle(theName);
  324.     itsWindow->Select();            /* Don't forget to make the window active */
  325. }
  326.  
  327.  
  328.  
  329. /***
  330.  * BuildWindow
  331.  *
  332.  *    Replace the old BuildWindow with this one...
  333.  *
  334.  ***/
  335.  
  336. void CStarterDoc::BuildWindow (Handle theData)
  337. {
  338.     CScrollPane        *theScrollPane;
  339.     CStarterPane    *thePanorama;
  340.     LongRect            panFrame;        /* the frame of the panorama */
  341.  
  342.     itsWindow = new( CWindow );
  343.     itsWindow->IWindow( WINDStarter, FALSE, gDesktop, this );
  344.     
  345.     theScrollPane = new( CScrollPane );
  346.  
  347.     theScrollPane->IScrollPane( itsWindow, this, 0, 0, 0, 0,  /* width, height = 0 */
  348.                                 sizELASTIC, sizELASTIC,
  349.                                 TRUE, TRUE, TRUE );
  350.     theScrollPane->FitToEnclFrame( TRUE, TRUE );
  351.     theScrollPane->SetSteps( 10, 10 );
  352.  
  353.     thePanorama = new( CStarterPane );
  354.     thePanorama->IStarterPane( theScrollPane, this, 0, 0, 0, 0,
  355.                                     sizELASTIC, sizELASTIC );
  356.     thePanorama->FitToEnclosure( TRUE, TRUE );
  357.     theScrollPane->InstallPanorama( thePanorama );
  358.     
  359.     itsMainPane = thePanorama;
  360.     itsGopher = thePanorama;
  361.  
  362.     /* Make the panorama be as large as the interior of a zoomed-out window. 
  363.         (When the window is zoomed out, the scrollbars will be inactive;  any
  364.         smaller window will have active scrollbars.  Alternatively, you could
  365.         call GetFrame and SetBounds AFTER calling PlaceNewWindow;  this would
  366.         make the panorama as big as the interior of the default window.) 
  367.     */
  368.  
  369.     itsWindow->Zoom(inZoomOut);            
  370.     thePanorama->GetFrame(&panFrame);
  371.     thePanorama->SetBounds(&panFrame);    
  372.     
  373.     gDecorator->PlaceNewWindow( itsWindow );
  374.  
  375. }
  376.  
  377.  
  378. /***
  379.  * DoSave
  380.  *
  381.  *    This method handles what happens when the user chooses Save from the
  382.  *    File menu. This method should return TRUE if the file save was successful.
  383.  *    If there is no file associated with the document, you should send a
  384.  *    DoSaveFileAs() message.
  385.  *
  386.  ***/
  387.  
  388. Boolean CStarterDoc::DoSave(void)
  389.  
  390. {
  391.         /**
  392.          **    If you closed your file in your NewFile() method,
  393.          **    you'll need a different way than this to determine
  394.          **    if there's a file associated with your document.
  395.          **
  396.          **/
  397.  
  398.     if (itsFile == NULL)
  399.         return(DoSaveFileAs());
  400.     else {
  401.             
  402.         /**
  403.          **    In your application, this is where you'd
  404.          **    write out your file. if you left it open,
  405.          **    send the WriteSome() or WriteAll() mesages
  406.          **    to itsFile.
  407.          **
  408.          **/
  409.             
  410.         dirty = FALSE;                    /* Document is no longer dirty        */
  411.         gBartender->DisableCmd(cmdSave);
  412.         return(TRUE);                    /* Save was successful                */
  413.     }
  414. }
  415.  
  416.  
  417. /***
  418.  * DoSaveAs
  419.  *
  420.  *    This method handles what happens when the user chooses Save As… from
  421.  *    File menu. The default DoCommand() method for documents sends a DoSaveFileAs()
  422.  *    message which displays a standard put file dialog and sends this message.
  423.  *    The SFReply record contains all the information about the file you're about
  424.  *    to create.
  425.  *
  426.  ***/
  427.  
  428. Boolean CStarterDoc::DoSaveAs(SFReply *macSFReply)
  429.  
  430. {
  431.         /**
  432.          **    If there's a file associated with this document
  433.          **    already, close it. The Dispose() method for files
  434.          **    sends a Close() message to the file before releasing
  435.          **    its memory.
  436.          **
  437.          **/
  438.          
  439.     if (itsFile != NULL)
  440.         itsFile->Dispose();
  441.  
  442.  
  443.         /**
  444.          **    Create a new file, and then save it normally.
  445.          **
  446.          **/
  447.  
  448.     itsFile = new(CDataFile);
  449.     ((CDataFile *)itsFile)->IDataFile();
  450.     itsFile->SFSpecify(macSFReply);
  451.     itsFile->CreateNew(gSignature, 'TEXT');
  452.     itsFile->Open(fsRdWrPerm);
  453.     
  454.     itsWindow->SetTitle(macSFReply->fName);
  455.  
  456.     return( DoSave() );
  457. }
  458.  
  459.  
  460. /***
  461.  * DoRevert
  462.  *
  463.  *    If your application supports the Revert command, this method
  464.  *    should close the current file (without writing anything out)
  465.  *    and read the last saved version of the file.
  466.  *
  467.  ***/
  468.  
  469. void CStarterDoc::DoRevert(void)
  470.  
  471. {
  472. }
  473.